package org.dromara.timemate.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.timemate.domain.*;
import org.dromara.timemate.domain.bo.DataAcquisitionBo;
import org.dromara.timemate.domain.vo.DataAcquisitionVo;
import org.dromara.timemate.domain.vo.DeviceManageVo;
import org.dromara.timemate.mapper.*;
import org.dromara.timemate.service.DataAcquisitionService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
public class DataAcquisitionServiceImpl implements DataAcquisitionService {
    private final SysUserMapper userMapper;
    private final DeviceInfoMapper deviceInfoMapper;
    private final MealMetricsMapper mealMetricsMapper;
    private final DailyWaterIntakeMapper waterIntakeMapper;
    private final DailySleepQualityMapper sleepQualityMapper;
    private final MoodMetricsMapper moodMetricsMapper;
    private final DailyStepsMapper dailyStepsMapper;
    private final DailyDeviceMetricsMapper metricsMapper;


    @Override
    public TableDataInfo<DataAcquisitionVo> queryPageList(DataAcquisitionBo bo, PageQuery pageQuery) {
        String phonenumber = bo.getPhonenumber();
        String deviceType = bo.getDeviceType();
        String deviceName = bo.getDeviceName();
        Date recordDay = bo.getRecordDay();
        Page<DataAcquisitionVo> page = pageQuery.build();

        Integer pageNum = (int) page.getCurrent();
        Integer pageSize = (int) page.getSize();
        Integer start = (pageNum - 1) * pageSize;

        List<DataAcquisitionVo> dataAcquisitionVos = deviceInfoMapper.selectByParamsPageQuery(phonenumber, deviceType, deviceName, recordDay, start, pageSize);
        long total = deviceInfoMapper.selectByParamsCount(phonenumber, deviceType, deviceName, recordDay);
        TableDataInfo<DataAcquisitionVo> TableDataInfo = new TableDataInfo<>();
        TableDataInfo.setRows(dataAcquisitionVos);
        TableDataInfo.setCode(HttpStatus.SUCCESS);
        TableDataInfo.setMsg("查询成功");
        TableDataInfo.setTotal(total);
        return TableDataInfo;
    }

    @Override
    @Transactional
    public void addDataAcquisition(DataAcquisitionBo dataAcquisitionBo) {
        Long deviceId = dataAcquisitionBo.getId();//设备id
        String tenantId = LoginHelper.getTenantId();
        Date recordDay = dataAcquisitionBo.getRecordDay();
        DeviceInfo deviceInfo = deviceInfoMapper.selectById(deviceId);
        Long wearerId = deviceInfo.getWearerId();
//1、食物指标表参数
        String foodSurplus = dataAcquisitionBo.getFoodSurplus();
        String carbohydrate = dataAcquisitionBo.getCarbohydrate();
        String protein = dataAcquisitionBo.getProtein();
        String vitamin = dataAcquisitionBo.getVitamin();
//2、心情指标表参数
        BigDecimal moodScore = dataAcquisitionBo.getMoodScore();
//3、水分表参数
        String intakeAmount = dataAcquisitionBo.getIntakeAmount();//水分摄入量
//4、睡眠表参数
        BigDecimal deepDuration = dataAcquisitionBo.getDeepDuration();
//5、步数表参数
        Integer steps = dataAcquisitionBo.getSteps();
//6、设备指标参数
        String diastolicPressure = dataAcquisitionBo.getDiastolicPressure();//舒张压
        String systolicPressure = dataAcquisitionBo.getSystolicPressure();
        String pulseRate = dataAcquisitionBo.getPulseRate();
        String heartRate = dataAcquisitionBo.getHeartRate();

//通过deviceId，tenantId，recordDay插入各自的均衡表

        MealMetrics mealMetrics = new MealMetrics();
        mealMetrics.setDeviceId(deviceId);
        mealMetrics.setTenantId(tenantId);
        mealMetrics.setFoodSurplus(foodSurplus);
        mealMetrics.setRecordDay(recordDay);
        mealMetrics.setCarbohydrate(carbohydrate);
        mealMetrics.setProtein(protein);
        mealMetrics.setVitamin(vitamin);
        mealMetricsMapper.insert(mealMetrics);

        DailyWaterIntake dailyWaterIntake = new DailyWaterIntake();
        dailyWaterIntake.setDeviceId(deviceId);
        dailyWaterIntake.setTenantId(tenantId);
        dailyWaterIntake.setWearerId(wearerId);
        dailyWaterIntake.setIntakeAmount(intakeAmount);
        dailyWaterIntake.setRecordDay(recordDay);
        waterIntakeMapper.insert(dailyWaterIntake);

        DailySleepQuality dailySleepQuality = new DailySleepQuality();
        dailySleepQuality.setDeviceId(deviceId);
        dailySleepQuality.setTenantId(tenantId);
        dailySleepQuality.setWearerId(wearerId);
        dailySleepQuality.setDeepDuration(deepDuration);
        dailySleepQuality.setRecordDay(recordDay);
        sleepQualityMapper.insert(dailySleepQuality);

//通过设备id，查出wearerId，以此来添加心情指标
        MoodMetrics moodMetrics = new MoodMetrics();
        moodMetrics.setWearerId(wearerId);
        moodMetrics.setTenantId(tenantId);
        moodMetrics.setMoodScore(moodScore);
        moodMetricsMapper.insert(moodMetrics);

        DailySteps dailySteps = new DailySteps();
        dailySteps.setDeviceId(deviceId);
        dailySteps.setTenantId(tenantId);
        dailySteps.setWearerId(wearerId);
        dailySteps.setSteps(steps);
        dailySteps.setRecordDay(recordDay);
        dailyStepsMapper.insert(dailySteps);

        DailyDeviceMetrics deviceMetrics = new DailyDeviceMetrics();
        deviceMetrics.setDeviceId(deviceId);
        deviceMetrics.setTenantId(tenantId);
        deviceMetrics.setPulseRate(pulseRate);
        deviceMetrics.setDiastolicPressure(diastolicPressure);
        deviceMetrics.setSystolicPressure(systolicPressure);
        deviceMetrics.setHeartRate(heartRate);
        deviceMetrics.setRecordDay(recordDay);
        metricsMapper.insert(deviceMetrics);


    }

    @Override
    @Transactional
    public void updateByBo(DataAcquisitionBo dataAcquisitionBo) {
        Long deviceId = dataAcquisitionBo.getId();//设备id
        Date recordDay = dataAcquisitionBo.getRecordDay();
        //1、食物指标表参数
        String foodSurplus = dataAcquisitionBo.getFoodSurplus();
        String carbohydrate = dataAcquisitionBo.getCarbohydrate();
        String protein = dataAcquisitionBo.getProtein();
        String vitamin = dataAcquisitionBo.getVitamin();
//2、心情指标表参数
        BigDecimal moodScore = dataAcquisitionBo.getMoodScore();
//3、水分表参数
        String intakeAmount = dataAcquisitionBo.getIntakeAmount();//水分摄入量
//4、睡眠表参数
        BigDecimal deepDuration = dataAcquisitionBo.getDeepDuration();
//5、步数表参数
        Integer steps = dataAcquisitionBo.getSteps();
//6、设备指标参数
        String diastolicPressure = dataAcquisitionBo.getDiastolicPressure();//舒张压
        String systolicPressure = dataAcquisitionBo.getSystolicPressure();
        String pulseRate = dataAcquisitionBo.getPulseRate();
        String heartRate = dataAcquisitionBo.getHeartRate();
//食物表修改
        LambdaUpdateWrapper<MealMetrics> mealWrapper = Wrappers.lambdaUpdate(MealMetrics.class)
            .eq(MealMetrics::getDeviceId, deviceId)
            .set(recordDay != null, MealMetrics::getRecordDay, recordDay)
            .set(StringUtils.isNotBlank(foodSurplus), MealMetrics::getFoodSurplus, foodSurplus)
            .set(StringUtils.isNotBlank(carbohydrate), MealMetrics::getCarbohydrate, carbohydrate)
            .set(StringUtils.isNotBlank(protein), MealMetrics::getProtein, protein)
            .set(StringUtils.isNotBlank(vitamin), MealMetrics::getVitamin, vitamin);
        mealMetricsMapper.update(mealWrapper);
//水分表修改
        LambdaUpdateWrapper<DailyWaterIntake> waterWrapper = Wrappers.lambdaUpdate(DailyWaterIntake.class)
            .eq(DailyWaterIntake::getDeviceId, deviceId)
            .set(recordDay != null, DailyWaterIntake::getRecordDay, recordDay)
            .set(StringUtils.isNotBlank(intakeAmount), DailyWaterIntake::getIntakeAmount, intakeAmount);
        waterIntakeMapper.update(waterWrapper);
//睡眠表修改
        LambdaUpdateWrapper<DailySleepQuality> sleepWrapper = Wrappers.lambdaUpdate(DailySleepQuality.class)
            .eq(DailySleepQuality::getDeviceId, deviceId)
            .set(recordDay != null, DailySleepQuality::getRecordDay, recordDay)
            .set(deepDuration != null, DailySleepQuality::getDeepDuration, deepDuration);
        sleepQualityMapper.update(sleepWrapper);
//心情表修改
        DeviceInfo deviceInfo = deviceInfoMapper.selectById(deviceId);
        Long wearerId = deviceInfo.getWearerId();
        LambdaUpdateWrapper<MoodMetrics> moodWrapper = Wrappers.lambdaUpdate(MoodMetrics.class)
            .eq(MoodMetrics::getWearerId, wearerId)
            .set(moodScore != null, MoodMetrics::getMoodScore, moodScore);
        moodMetricsMapper.update(moodWrapper);
//步数表修改
        LambdaUpdateWrapper<DailySteps> StepsWrapper = Wrappers.lambdaUpdate(DailySteps.class);
        StepsWrapper.eq(DailySteps::getDeviceId, deviceId)
            .set(steps!=null, DailySteps::getSteps, steps)
            .set(recordDay != null, DailySteps::getRecordDay, recordDay);
        dailyStepsMapper.update(StepsWrapper);
//设备指标修改
        LambdaUpdateWrapper<DailyDeviceMetrics> metricsWrapper = Wrappers.lambdaUpdate(DailyDeviceMetrics.class);
        metricsWrapper.eq(DailyDeviceMetrics::getDeviceId, deviceId)
                .set(StringUtils.isNotBlank(diastolicPressure),DailyDeviceMetrics::getDiastolicPressure,diastolicPressure)
            .set(StringUtils.isNotBlank(systolicPressure),DailyDeviceMetrics::getSystolicPressure,systolicPressure)
            .set(StringUtils.isNotBlank(pulseRate),DailyDeviceMetrics::getPulseRate,pulseRate)
            .set(StringUtils.isNotBlank(heartRate),DailyDeviceMetrics::getHeartRate,heartRate)
            .set(recordDay != null, DailyDeviceMetrics::getRecordDay, recordDay);;
        metricsMapper.update(metricsWrapper);

    }

    @Override
    @Transactional
    public void deleteWithValidByIds(List<DataAcquisitionBo> list) {
        for (DataAcquisitionBo dataAcquisitionBo : list) {
            Long deviceId = dataAcquisitionBo.getId();
            Long wearerId = deviceInfoMapper.selectById(deviceId).getWearerId();
            Date recordDay = dataAcquisitionBo.getRecordDay();
            metricsMapper.delete(Wrappers.lambdaQuery(DailyDeviceMetrics.class).eq(DailyDeviceMetrics::getDeviceId,deviceId).eq(DailyDeviceMetrics::getRecordDay,recordDay));
            dailyStepsMapper.delete(Wrappers.lambdaQuery(DailySteps.class).eq(DailySteps::getDeviceId,deviceId).eq(DailySteps::getRecordDay,recordDay));
            sleepQualityMapper.delete(Wrappers.lambdaQuery(DailySleepQuality.class).eq(DailySleepQuality::getDeviceId,deviceId).eq(DailySleepQuality::getRecordDay,recordDay));
            waterIntakeMapper.delete(Wrappers.lambdaQuery(DailyWaterIntake.class).eq(DailyWaterIntake::getDeviceId,deviceId).eq(DailyWaterIntake::getRecordDay,recordDay));
            mealMetricsMapper.delete(Wrappers.lambdaQuery(MealMetrics.class).eq(MealMetrics::getDeviceId,deviceId).eq(MealMetrics::getRecordDay,recordDay));
            moodMetricsMapper.delete(Wrappers.lambdaQuery(MoodMetrics.class).eq(MoodMetrics::getWearerId,wearerId));

        }



    }

    @Override
    public Collection<DeviceManageVo> queryAllDeviceInfo() {

        List<DeviceManageVo> allDeviceInfos = deviceInfoMapper.queryAllDeviceInfo();
        Set<DeviceManageVo> collect = allDeviceInfos.stream().collect(Collectors.toSet());
        return collect;
    }
}
